# coding=utf-8
"""
天眼查点击验证码
使用说明:
    bbox 参数在试用前请通过mouse_coordinates()方法获取需要截图的区域
    调用请使用:
        方法一 python 代码 " os.system('python ClickTheVerificationCode.py')"
        方法二 将SeleniumAuxiliary.py 封装成exe可直接调用
    本代码使用方法在SeleniumAuxiliary.py 文件下"os.system('python ClickTheVerificationCode.py')"
"""
import win32api
import win32con
import requests
from time import sleep
from hashlib import md5


class Configuration:
    """配置"""

    # 超级鹰账号
    ChaoJiYingUserName = '超级鹰账号'

    # 超级鹰密码
    ChaoJiYingPassWord = md5('超级鹰密码'.encode('utf8')).hexdigest()

    # 验证码类型     9004: 坐标多选,返回1~4个坐标,如:x1,y1|x2,y2|x3,y3
    soft_id = '9004'

    # 截取图片的坐标
    # 第一个参数 开始截图的x坐标
    # 第二个参数 开始截图的y坐标
    # 第三个参数 结束截图的x坐标
    # 第四个参数 结束截图的y坐标
    bbox = (805, 354, 1127, 495)

    # 提交按钮的坐标
    submit = (957, 579)


def mouse_coordinates():
    """获取鼠标当前位置的坐标: 用来选取需要截图的区域"""
    print(win32api.GetCursorPos())
    

def verification_code_screenshot():
    """验证码截图"""

    from PIL import ImageGrab
    im = ImageGrab.grab(Configuration().bbox)                                   # 截图图片保存为数组
    im.save('randomCode.png')                                                   # 将数组保存为图片


def click_coordinates(random_pic_str):
    """鼠标点击对应的验证码"""

    click_list = [tuple(map(int, i.split(',')))                                 # 将超级鹰返回的坐标整合成元组
                  for i in random_pic_str.split('|')]

    # 循环点击
    for click in click_list:
        point = (Configuration().bbox[0] + click[0],                            # 根据截图的初始位置计算需要点击的位置
                 Configuration().bbox[1] + click[1])
        win32api.SetCursorPos(point)                                            # 鼠标移动到该点
        sleep(0.2)
        win32api.mouse_event(win32con.MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0)         # 点击鼠标左键
        win32api.mouse_event(win32con.MOUSEEVENTF_LEFTUP, 0, 0, 0, 0)           # 释放鼠标左键
        print('Click Coordinates...', point)
    sleep(0.2)

    # 点击提交按钮
    win32api.SetCursorPos(Configuration().submit)
    win32api.mouse_event(win32con.MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0)
    win32api.mouse_event(win32con.MOUSEEVENTF_LEFTUP, 0, 0, 0, 0)


class ChaojiyingClient(object):
    """超级鹰打码平台类"""

    def __init__(self):
        self.conf = Configuration()                                             # 加载配置
        self.base_params = {
            'user': self.conf.ChaoJiYingUserName,
            'pass2': self.conf.ChaoJiYingPassWord,
            'softid': self.conf.soft_id,
        }
        self.headers = {
            'Connection': 'Keep-Alive',
            'User-Agent': 'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0)',
        }

    def post_pic(self, im):
        """
        图片发送给超级鹰
        im: 图片字节
        codetype: 题目类型 参考 http://www.chaojiying.com/price.html
        """

        params = {
            'codetype': self.conf.soft_id,
        }
        params.update(self.base_params)
        files = {'userfile': ('ccc.jpg', im)}
        r = requests.post('http://upload.chaojiying.net/Upload/Processing.php', data=params, files=files, headers=self.headers)
        return r.json()

    def report_error(self, im_id):
        """
        向超级鹰提交错误id
        im_id:报错题目的图片ID
        """

        params = {
            'id': im_id,
        }
        params.update(self.base_params)
        r = requests.post('http://upload.chaojiying.net/Upload/ReportError.php', data=params, headers=self.headers)
        return r.json()


def main():
    """主函数"""
    verification_code_screenshot()                              # 截取验证码
    cjy = ChaojiyingClient()                                    # 实例化超级鹰类
    im = open('randomCode.png', 'rb').read()                    # 打开本地图片为字节流
    random_data = cjy.post_pic(im)                              # 交给超级鹰
    if random_data['err_str'] == 'OK':                          # 如果状态码是OK
        random_pic_str = random_data['pic_str']                 # 获取返回的坐标
        click_coordinates(random_pic_str)                       # 交给鼠标点击函数
    else:
        print(random_data)
    sleep(1)


if __name__ == "__main__":
    main()
    # mouse_coordinates()